package dao

import (
	"context"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/pkg/errors"
	"github.com/rs/zerolog/log"
	"github.com/spf13/viper"
	"github.com/xormplus/xorm"
	_ "satellite/init"
	"sort"
	"sync"
	"time"
)

var Engines *engines

func init() {
	GetEngines()
}

type engines struct {
	Configs map[string]string
	engines map[string]*Engine //多个mysql实例
	ctx     string             //当前上下文的默认实例
}

var onceEngine sync.Once

// GetEngines
// @Description: 创建并初始化*engines
// @return *engines
func GetEngines() *engines {
	onceEngine.Do(func() {
		Engines = &engines{
			Configs: make(map[string]string),
			engines: make(map[string]*Engine),
			ctx:     "",
		}
		log.Info().Msg("engines init")
		Engines.init()
	})
	return Engines
}

func (e *engines) init() {
	e.Configs = viper.GetStringMapString("mysql.dsn")
	if len(e.Configs) == 0 {
		log.Panic().Msg("no dsn find in config")
	}
	for name, dsn := range e.Configs {
		engine, err := xorm.NewEngine("mysql", dsn)
		if err != nil {
			log.Panic().Err(err).Str("name", name).Msg("xorm create driver fail")
		}
		debug := viper.GetBool("mysql.debug")
		engine.ShowSQL(debug)
		err = engine.Ping()
		if err != nil {
			log.Panic().Err(err).Msg("database ping fail")
		}
		e.engines[name] = &Engine{engine}
	}
}

func (e *engines) SetCtx(name string) error {
	if _, ok := e.engines[name]; !ok {
		return errors.New("name not registered")
	}
	e.ctx = name
	return nil
}

func (e engines) WatchGroupReplicationStatus(ctx context.Context) {
	//按顺序整理待观察列表
	keyList := make([]string, 0, len(e.engines))
	for k := range e.engines {
		keyList = append(keyList, k)
	}
	sort.Strings(keyList)
	//实现观察逻辑
	select {
	case <-ctx.Done():
		return
	default:
		fmt.Printf("**********%v**********", time.Now())
		for _, name := range keyList {
			engine := e.engines[name]
			status, err := engine.GetGroupStatus()
			if err != nil {
				return
			}
			status = status
		}
	}
}
